#pragma once
#include <iostream>
using namespace std;

class ListNode
{
public:
	ListNode(int x = 0, ListNode* next = nullptr) :_x(x), _next(next) {}
	int _x;
	ListNode* _next;
};

class List
{
public:
	List() :_head(nullptr) {}
	void InsertAfter(int pos, int data)
	{
		ListNode* newnode = new ListNode(data);
		ListNode* cur = _head;
		while (pos--)
		{
			cur = cur->_next;
		}
		newnode->_next = cur->_next;
		cur->_next = newnode;
	}
	void InsertBefore(int pos, int data)
	{
		ListNode* newnode = new ListNode(data);
		ListNode* cur = _head;
		ListNode* prev = nullptr;
		while (pos--)
		{
			prev = cur;
			cur = cur->_next;
		}
		if (prev == nullptr)
		{
			newnode->_next = _head;
			_head = newnode;
		}
		else
		{
			newnode->_next = prev->_next;
			prev->_next = newnode;
		}
	}
	void Erase(int pos)
	{
		ListNode* cur = _head;
		ListNode* prev = _head;
		while (pos--)
		{
			prev = cur;
			cur = cur->_next;
		}
		prev->_next = cur->_next;
		delete cur;
	}
	void Pushfront(int x)
	{
		InsertBefore(0, x);
	}
	void PushBack(int x)
	{
		ListNode* newnode = new ListNode(x);
		if (_head == nullptr)
		{
			_head = newnode;
		}
		else
		{
			ListNode* cur = _head;
			while (cur->_next)
			{
				cur = cur->_next;
			}
			cur->_next = newnode;
		}
	}
	void PopFront()
	{
		Erase(0);
	}
	void PopBack()
	{
		ListNode* cur = _head;
		ListNode* prev = _head;
		while (cur->_next)
		{
			prev = cur;
			cur = cur->_next;
		}
		prev->_next = nullptr;
		delete cur;
	}
	void Print()
	{
		ListNode* cur = _head;
		cout << cur->_x << "->";
		while (cur->_next)
		{
			cur = cur->_next;
			cout << cur->_x << "->";
		}
		cout << "null" << endl;
	}
private:
	ListNode* _head;
};